// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//


// This file is a drop-in copy of Arrow's C Data Interface, as defined in:
//   https://arrow.apache.org/docs/format/CDataInterface.html

#pragma once

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// These macros prevent re-definition in case multiple headers try to define
// them.
#ifndef ARROW_C_DATA_INTERFACE
#define ARROW_C_DATA_INTERFACE

#define ARROW_FLAG_DICTIONARY_ORDERED 1
#define ARROW_FLAG_NULLABLE 2
#define ARROW_FLAG_MAP_KEYS_SORTED 4

struct ArrowSchema {
    // Array type description
    const char *format{nullptr};
    const char *name{nullptr};
    const char *metadata{nullptr};
    int64_t flags{0};
    int64_t n_children{0};
    struct ArrowSchema **children{nullptr};
    struct ArrowSchema *dictionary{nullptr};

    // Release callback
    void (*release)(struct ArrowSchema *);

    // Opaque producer-specific data
    void *private_data;
};

struct ArrowArray {
    // Array data description
    int64_t length{0};
    int64_t null_count{0};
    int64_t offset{0};
    int64_t n_buffers{0};
    int64_t n_children{0};
    const void **buffers{nullptr};
    struct ArrowArray **children{nullptr};
    struct ArrowArray *dictionary{nullptr};

    // Release callback
    void (*release)(struct ArrowArray *);

    // Opaque producer-specific data
    void *private_data;
};

#endif // ARROW_C_DATA_INTERFACE

// EXPERIMENTAL: C stream interface

#ifndef ARROW_C_STREAM_INTERFACE
#define ARROW_C_STREAM_INTERFACE

struct ArrowArrayStream {
    // Callback to get the stream type
    // (will be the same for all arrays in the stream).
    //
    // Return value: 0 if successful, an `errno`-compatible error code otherwise.
    //
    // If successful, the ArrowSchema must be released independently from the
    // stream.
    int (*get_schema)(struct ArrowArrayStream *, struct ArrowSchema *out);

    // Callback to get the next array
    // (if no error and the array is released, the stream has ended)
    //
    // Return value: 0 if successful, an `errno`-compatible error code otherwise.
    //
    // If successful, the ArrowArray must be released independently from the
    // stream.
    int (*get_next)(struct ArrowArrayStream *, struct ArrowArray *out);

    // Callback to get optional detailed error information.
    // This must only be called if the last stream operation failed
    // with a non-0 return code.
    //
    // Return value: pointer to a null-terminated character array describing
    // the last error, or NULL if no description is available.
    //
    // The returned pointer is only valid until the next operation on this stream
    // (including release).
    const char * (*get_last_error)(struct ArrowArrayStream *);

    // Release callback: release the stream's own resources.
    // Note that arrays returned by `get_next` must be individually released.
    void (*release)(struct ArrowArrayStream *);

    // Opaque producer-specific data
    void *private_data;
};

#endif // ARROW_C_STREAM_INTERFACE

#ifdef __cplusplus
}
#endif
